<template>
  <div class="upload-demo light-upload">
    <div class="switch-btn-bar">
      <el-button @click="msgOne()" :class="['switch-btn', msg === 1 ? 'active' : '']" type="primary" size="medium"
        round>fofa</el-button>
      <el-button @click="msgTwo()" :class="['switch-btn', msg === 2 ? 'active' : '']" type="primary" size="medium"
        round>zoomeye</el-button>
    </div>

    <div v-if="this.msg == 1">
      <div class="search-bar">
        <el-input placeholder="ip" v-model="user.ip" class="input-id search-input" />
        <el-input placeholder="端口" v-model="user.fofaPort" class="input-id search-input" />
        <el-input placeholder="域名" v-model="user.fofaDomain" class="input-id search-input" />
        <el-button @click="submitFofa" class="search-btn">搜索</el-button>
      </div>

      <div class="btn-bar">
        <el-button type="primary" @click="handleUpload()" class="dark-btn">下载json文件</el-button>
        <el-button type="primary" @click="downloadXmlVpsList()" class="dark-btn">下载xml文件</el-button>
        <el-button type="primary" @click="downloadXlsVpsList()" class="dark-btn">下载xls文件</el-button>
        <el-button type="primary" class="dark-btn" style="margin-left: 360px;" @click="fofaAdd">添加</el-button>
      </div>

      <el-table :data="list" stripe style="width: 100%" @selection-change="handleSelectionChange" class="dark-table"
        border>
        <el-table-column type="selection" width="55" align="center"></el-table-column>
        <el-table-column prop="ip" label="IP" align="center"></el-table-column>
        <el-table-column prop="port" label="端口" align="center"></el-table-column>
        <el-table-column prop="domain" label="域名" align="center">

        </el-table-column>
        <el-table-column prop="country_name" label="国家名称" align="center"></el-table-column>
        <el-table-column prop="base_protocol" label="基础协议" align="center"></el-table-column>
        <el-table-column prop="city" label="城市" align="center"></el-table-column>
        <el-table-column label="操作" width="210" align="center">
          <template #default="scope">
            <el-button size="mini" @click="fofaEdit(scope.row)">修改</el-button>
            <el-button size="mini" @click="handle(scope.row)">详情</el-button>
            <el-button size="mini" type="danger" @click="fofaDelete(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div v-else>
      <div class="search-bar">
        <el-input placeholder="ip" v-model="zoomeye.ip" class="input-id search-input" />
        <el-input placeholder="端口" v-model="zoomeye.port" class="input-id search-input" />
        <el-input placeholder="系统" v-model="zoomeye.os" class="input-id search-input" />
        <el-button @click="submitzoomeye" class="search-btn">搜索</el-button>
      </div>
      <div class="btn-bar">
        <el-button type="primary" @click="handleUploadZoomeye()" class="dark-btn">下载json文件</el-button>
        <el-button type="primary" @click="downloadXmlVpsListZoomeye()" class="dark-btn">下载xml文件</el-button>
        <el-button type="primary" @click="downloadXlsVpsListZoomeye()" class="dark-btn">下载xls文件</el-button>
        <el-button type="primary" class="dark-btn" style="margin-left: 360px;" @click="AddZoomeye">添加</el-button>
      </div>
      <el-table :data="listzoomeye" stripe style="width: 100%" @selection-change="handleSelectionChangeZoomeye"
        class="dark-table" border>
        <el-table-column type="selection" width="55" align="center"></el-table-column>
        <el-table-column prop="ip" label="IP" align="center"></el-table-column>
        <el-table-column prop="port" label="端口号" align="center"></el-table-column>
        <el-table-column prop="organization_CN" label="运营" align="center"></el-table-column>
        <el-table-column prop="service" label="服务" align="center"></el-table-column>
        <el-table-column prop="url" label="URL" align="center" show-overflow-tooltip></el-table-column>
        <el-table-column prop="city_name_CN" label="城市" align="center"></el-table-column>
        <el-table-column label="操作" width="210" align="center">
          <template #default="scope">
            <el-button size="mini" @click="handleZoomeyeEdit(scope.row)">修改</el-button>
            <el-button size="mini" @click="handleZoomeye(scope.row)">详情</el-button>
            <el-button size="mini" type="danger" @click="deleteHandleZoomeye(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <!-- fofa详情弹框 -->
    <listitem v-if="dialogVisible" :visible.sync="dialogVisible">
      <template v-slot:default>
        <div class="detail-card wide-detail-card">
          <div class="detail-title">fofa详情</div>
          <div class="detail-grid-row3">
            <div class="detail-row" v-for="(item, idx) in fofaDetailFields" :key="idx">
              <span class="detail-label">{{ item.label }}</span>
              <span class="detail-value" :title="item.value && item.value.length > 18 ? item.value : ''">
                <template v-if="item.value && item.value.length > 10">
                  <el-tooltip effect="dark" :content="item.value" placement="top">
                    <span>{{ item.value.slice(0, 10) + '...' }}</span>
                  </el-tooltip>
                </template>
                <template v-else>
                  {{ item.value }}
                </template>
              </span>
            </div>
          </div>
        </div>
      </template>
    </listitem>
    <!-- zoomeye详情弹框 -->
    <zoomeye v-if="dialogVisibleZoomeye" :visible.sync="dialogVisibleZoomeye">
      <template v-slot:default>
        <div class="detail-card wide-detail-card">
          <div class="detail-title">zoomeye详情</div>
          <div class="detail-grid-row3">
            <div class="detail-row" v-for="(item, idx) in zoomeyeDetailFields" :key="idx">
              <span class="detail-label">{{ item.label }}</span>
              <span class="detail-value" :title="item.value && item.value.length > 18 ? item.value : ''">
                {{ item.label === '时间：' && item.value ? formatTime(item.value) : (item.value && item.value.length > 18 ?
                  (item.value.slice(0, 10) + '...') : item.value) }}
              </span>
            </div>
          </div>
        </div>
      </template>
    </zoomeye>
    <fofa :form-data="fofaData" :mode="dialogMode" :visible.sync="dialogVisibleFofa"
      @submit-complete="handleSubmitComplete"></fofa>
    <zoomeyenName :visible.sync="dialogVisibleZoomeyenName" @submit-zoomeye="submitZoomeyetow"></zoomeyenName>
    <zoomeyeEdit :visible.sync="dialogVisibleZoomeyenEdit" :form-data="zoomeyeData"
      @submit-zoomeyeOne="submitZoomeyeOne">
    </zoomeyeEdit>
  </div>
</template>

<script>
import { fofaVpsList, downloadJsonVpsList, downloadXmlVpsList, downloadXlsVpsList, selseloadXlsVpsList, downloadinsertList, downloaddeleteList, downloadupdateList } from "@/api/uploudlist/index.js";
import { zoomeyeVpsList, zoomeyeJsonsList, zoomeyeXmlList, zoomeyeXlsList, zoomeyeSelectXlsList, zoomeyedeleteList, zoomeyeinsertList, zoomeyeupdateList } from "@/api/zoomeye/index.js";
import listitem from './uploditem/listitem.vue';
import zoomeye from './uploditem/zoomeye.vue';
import fofa from "./PopupLayer/fofa.vue"
import zoomeyenName from "./PopupLayer/zoomeye.vue";
import zoomeyeEdit from "./PopupLayer/zoomeyeEdit.vue";
export default {
  name: "UploudList",
  components: { listitem, zoomeye, fofa, zoomeyenName, zoomeyeEdit },
  mounted() {
    this.fofaVpsListll();
    this.zoomeyeVpsList();

  },
  data() {
    return {
      dialogMode: "",
      list: [],
      ids: [],
      dialogVisible: false,
      detailData: null,
      msg: 1,
      listzoomeye: [],
      idszoomeye: [],
      dialogVisibleZoomeye: false,
      user: {
        ip: '',
        fofaPort: '',
        fofaDomain: ''
      },
      zoomeye: {
        ip: '',
        port: '',
        os: ''
      },
      dialogVisibleFofa: false,
      fofaData: {},
      dialogVisibleZoomeyenName: false,
      dialogVisibleZoomeyenEdit: false,
      zoomeyeData: {},
      fofaId: "",
    };
  },
  watch: {
    user: {
      handler(newVal) {
        const { ip, fofaPort, fofaDomain } = newVal;
        const allEmpty = !ip && !fofaPort && !fofaDomain;

        if (allEmpty) {
          this.fofaVpsListll(); // 调你原来加载初始表格的方法
        }
      },
      deep: true
    },
    zoomeye: {
      handler(newVal) {
        const { ip, port, or } = newVal;
        const allEmpty = !ip && !port && !or;

        if (allEmpty) {
          this.zoomeyeVpsList(); // 调你原来加载初始表格的方法
        }
      },
      deep: true
    }
  },
  computed: {
    fofaDetailFields() {
      const data = this.detailData || {};

      return [
        { label: 'ASN：', value: data["asn"] || '' },
        { label: 'Banner：', value: data["banner"] || '' },
        { label: 'Banner FID：', value: data["banner_fid"] || '' },
        { label: 'Banner Hash：', value: data["banner_hash"] || '' },
        { label: '基础协议：', value: data["base_protocol"] || '' },

        // 证书相关
        { label: '证书域名：', value: data["cert.domain"] || '' },
        { label: '证书颁发者CN：', value: data["cert.issuer.cn"] || '' },
        { label: '证书颁发者组织：', value: data["cert.issuer.org"] || '' },
        { label: '证书起始时间：', value: data["cert.not_before"] || '' },
        { label: '证书截止时间：', value: data["cert.not_after"] || '' },
        { label: '证书序列号：', value: data["cert.sn"] || '' },
        { label: '证书持有者CN：', value: data["cert.subject.cn"] || '' },
        { label: '证书持有者组织：', value: data["cert.subject.org"] || '' },

        { label: '城市：', value: data["city"] || '' },
        { label: '国家缩写：', value: data["country"] || '' },
        { label: '国家名称：', value: data["country_name"] || '' },
        { label: '创建时间：', value: data["createTime"] || '' },
        { label: '创建用户：', value: data["createUser"] || '' },

        { label: '域名：', value: data["domain"] || '' },
        { label: 'Header：', value: data["header"] || '' },
        { label: 'Header Hash：', value: data["header_hash"] || '' },
        { label: 'Host：', value: data["host"] || '' },
        { label: 'ICP备案：', value: data["icp"] || '' },
        { label: '记录ID：', value: data["id"] || '' },

        { label: 'IP地址：', value: data["ip"] || '' },
        { label: 'JARM指纹：', value: data["jarm"] || '' },
        { label: '纬度：', value: data["latitude"] || '' },
        { label: '链接：', value: data["link"] || '' },
        { label: '经度：', value: data["longitude"] || '' },
        { label: '节点名称：', value: data["node_name"] || '' },

        { label: '组织机构：', value: data["org"] || '' },
        { label: '操作系统：', value: data["os"] || '' },
        { label: '端口号：', value: data["port"] || '' },
        { label: '协议：', value: data["protocol"] || '' },
        { label: '地区：', value: data["region"] || '' },
        { label: '备注：', value: data["remark"] || '' },

        { label: '资源类型：', value: data["resourceType"] || '' },
        { label: '服务器信息：', value: data["server"] || '' },
        { label: '网页标题：', value: data["title"] || '' },

        // TLS 信息
        { label: 'TLS JA3S：', value: data["tls.ja3s"] || '' },
        { label: 'TLS 版本：', value: data["tls.version"] || '' },
      ];
    },
    zoomeyeDetailFields() {
      const d = this.detailData || {};
      return [
        { label: 'IP 地址：', value: d.ip },
        { label: '端口号：', value: d.port },
        { label: 'URL：', value: d.url },
        { label: '服务：', value: d.service },
        { label: '协议（传输层）：', value: d.protocol_transport },
        { label: '协议探测信息：', value: d.protocol_probe },
        { label: '协议（应用层）：', value: d.protocol_application },
        { label: 'HTTP 标题：', value: d.http_title },
        { label: '网页标题信息：', value: d.title },
        { label: 'Web 应用名称：', value: d.webapp_name },
        { label: 'Web 应用版本：', value: d.webapp_version },
        { label: 'Web 应用官网：', value: d.webapp_url },
        { label: '组件名称：', value: d.component_name },
        { label: '组件版本：', value: d.component_version },
        { label: '产品名称：', value: d.product },
        { label: '版本信息：', value: d.version },
        { label: '数据库名称：', value: d.db_name },
        { label: '数据库版本：', value: d.db_version },
        { label: '设备类型：', value: d.device },
        { label: '系统名称：', value: d.system_name },
        { label: '系统发行版：', value: d.system_distrib },
        { label: '系统版本：', value: d.system_release },
        { label: '操作系统：', value: d.os },
        { label: '系统中文名：', value: d.system_chinese },
        { label: '服务器名称：', value: d.server_name },
        { label: '服务器版本：', value: d.server_version },
        { label: '服务器中文名：', value: d.server_chinese },
        { label: 'WAF 名称：', value: d.waf_name },
        { label: 'WAF 版本：', value: d.waf_version },
        { label: 'Banner 信息：', value: d.banner },
        { label: '指纹信息：', value: d.fingerprint },
        { label: 'JARM 指纹：', value: d.jarm },
        { label: '额外信息：', value: d.extrainfo },
        { label: 'rdns：', value: d.rdns },
        { label: 'hostname：', value: d.hostname },
        { label: '地理纬度：', value: d.lat },
        { label: '地理经度：', value: d.lon },
        { label: '城市（中文）：', value: d.city_name_CN },
        { label: '城市（英文）：', value: d.city_name_EN },
        { label: '城市 geoname_id：', value: d.city_geoname_id },
        { label: '行政区（中文）：', value: d.subdivisions_name_CN },
        { label: '行政区（英文）：', value: d.subdivisions_name_EN },
        { label: '行政区代码：', value: d.subdivisions_code },
        { label: '行政区 geoname_id：', value: d.subdivisions_geoname_id },
        { label: '国家（中文）：', value: d.country_name_CN },
        { label: '国家（英文）：', value: d.country_name_EN },
        { label: '国家代码：', value: d.country_code },
        { label: '国家 geoname_id：', value: d.country_geoname_id },
        { label: '大洲（中文）：', value: d.continent_name_CN },
        { label: '大洲（英文）：', value: d.continent_name_EN },
        { label: '大洲代码：', value: d.continent_code },
        { label: '大洲 geoname_id：', value: d.continent_geoname_id },
        { label: '运营组织（英文）：', value: d.organization },
        { label: '运营组织（中文）：', value: d.organization_CN },
        { label: 'ISP（运营商）：', value: d.isp },
        { label: 'IDC 信息：', value: d.idc },
        { label: '基站信息：', value: d.base_station },
        { label: 'ASN：', value: d.asn },
        { label: 'ASO：', value: d.aso },
        { label: '网站关键词：', value: d.keywords },
        { label: '描述信息：', value: d.description },
        { label: '备注信息：', value: d.remark },
        { label: '资源类型：', value: d.resourceType },
        { label: 'SSL 信息：', value: d.ssl },
        { label: 'PoweredBy：', value: d.PoweredBy },
        { label: '（surveying_time）：', value: d.surveying_time },
        { label: 'headers：', value: d.headers }
      ];
    }
  },
  methods: {
    submitZoomeyeOne(from) {
      console.log(from, 99999);

      zoomeyeupdateList(from).then((res) => {
        console.log(res);
        this.$message.success('修改成功');
        this.zoomeyeVpsList()
        this.dialogVisibleZoomeyenEdit = false;
      })
    },
    handleZoomeyeEdit(row) {
      console.log(row);
      this.zoomeyeData = { ...row }
      this.dialogVisibleZoomeyenEdit = true;
      this.dialogVisibleZoomeyenName = false;
    },
    submitZoomeyetow(form) {
      zoomeyeinsertList(form).then((res) => {
        console.log(res);
        this.$message.success('添加成功');
        this.zoomeyeVpsList()
        this.dialogVisibleZoomeyenName = false;
      })
    },
    async deleteHandleZoomeye(row) {

      try {
        await this.$confirm("此操作将永久删除该条记录, 是否继续?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        });
        const response = await zoomeyedeleteList(row.id);
        this.$message.success("用户删除成功");
        await this.zoomeyeVpsList();
      } catch (error) {
        this.$message.error("用户取消删除，请稍后再试");
      }
    },
    fofaAdd() {
      this.dialogMode = "add"
      // 清空fofaData
      this.fofaData = {};
      this.dialogVisibleFofa = true;
    },
    handleSubmitComplete(form) {
      // form为弹窗返回的数据
      const flatData = this.flattenObject(form);
      if (this.dialogMode === "add") {
        downloadinsertList(flatData).then((res) => {
          this.$message.success('添加成功');
          this.fofaVpsListll();
          this.dialogVisibleFofa = false;
        });
      } else if (this.dialogMode === "edit") {
        downloadupdateList(flatData).then((res) => {
          this.$message.success('修改成功');
          this.fofaVpsListll();
          this.dialogVisibleFofa = false;
        });
      }
    },
    async deleteHandleZoomeye(row) {

      try {
        await this.$confirm("此操作将永久删除该条记录, 是否继续?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        });
        const response = await zoomeyedeleteList(row.id);
        this.$message.success("用户删除成功");
        await this.zoomeyeVpsList();
      } catch (error) {
        this.$message.error("用户取消删除，请稍后再试");
      }
    },
    // submitzoomeye() {
    //   // 处理搜索逻辑
    //   console.log("搜索条件22222：", this.zoomeye);
    //   zoomeyeSelectXlsList(this.zoomeye).then((response) => {
    //     // 兼容 response 结构
    //     this.listzoomeye = response.data ? response.data : response;
    //     console.log(this.listzoomeye, "zoomeye数据22222");
    //   }).catch((error) => {
    //     console.error("Error fetching data:", error);
    //   });
    // },
    AddZoomeye() {
      this.dialogVisibleZoomeyenName = true;
    },
    fofaEdit(row) {
      this.dialogMode = "edit";
      // 深拷贝row，防止弹窗内修改影响表格
      this.fofaData = JSON.parse(JSON.stringify(row));
      this.dialogVisibleFofa = true;
    },
    flattenObject(obj, prefix = '') {
      let res = {};
      for (const key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
          const value = obj[key];
          const newKey = prefix ? `${prefix}.${key}` : key;
          if (value && typeof value === 'object' && !Array.isArray(value)) {
            Object.assign(res, this.flattenObject(value, newKey));
          } else {
            res[newKey] = value;
          }
        }
      }
      return res;
    },
    async fofaDelete(row) {
      console.log(row.id);

      try {
        await this.$confirm("此操作将永久删除该条记录, 是否继续?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        });
        const response = await downloaddeleteList(row.id);
        this.$message.success("用户删除成功");
        await this.fofaVpsListll();
        this.dialogVisibleZoomeyenName = false;
      } catch (error) {
        this.$message.error("用户取消删除，请稍后再试");
      }
    },
    submitzoomeye() {
      // 处理搜索逻辑
      console.log("搜索条件22222：", this.zoomeye);
      zoomeyeSelectXlsList(this.zoomeye).then((response) => {
        // 兼容 response 结构
        this.listzoomeye = response.data ? response.data : response;
        console.log(this.listzoomeye, "zoomeye数据22222");
      }).catch((error) => {
        console.error("Error fetching data:", error);
      });
    },
    AddZoomeye() {
      this.dialogVisibleZoomeyenName = true;
    },
    fofaEdit(row) {
      this.dialogMode = "edit";
      // 深拷贝row，防止弹窗内修改影响表格
      this.fofaData = JSON.parse(JSON.stringify(row));
      this.dialogVisibleFofa = true;
    },
    flattenObject(obj, prefix = '') {
      let res = {};
      for (const key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
          const value = obj[key];
          const newKey = prefix ? `${prefix}.${key}` : key;
          if (value && typeof value === 'object' && !Array.isArray(value)) {
            Object.assign(res, this.flattenObject(value, newKey));
          } else {
            res[newKey] = value;
          }
        }
      }
      return res;
    },
    async fofaDelete(row) {
      console.log(row.id);

      try {
        await this.$confirm("此操作将永久删除该条记录, 是否继续?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        });
        const response = await downloaddeleteList(row.id);
        this.$message.success("用户删除成功");
        await this.fofaVpsListll();
        this.dialogVisibleZoomeyenName = false;
      } catch (error) {
        this.$message.error("用户取消删除，请稍后再试");
      }
    },
    // submitzoomeye() {
    //   // 处理搜索逻辑
    //   console.log("搜索条件22222：", this.zoomeye);
    //   zoomeyeSelectXlsList(this.zoomeye).then((response) => {
    //     // 兼容 response 结构
    //     this.listzoomeye = response.data ? response.data : response;
    //     console.log(this.listzoomeye, "zoomeye数据22222");
    //   }).catch((error) => {
    //     console.error("Error fetching data:", error);
    //   });
    // },
    AddZoomeye() {
      this.dialogVisibleZoomeyenName = true;
    },
    fofaEdit(row) {
      this.dialogMode = "edit";
      // 深拷贝row，防止弹窗内修改影响表格
      this.fofaData = JSON.parse(JSON.stringify(row));
      this.dialogVisibleFofa = true;
    },
    flattenObject(obj, prefix = '') {
      let res = {};
      for (const key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
          const value = obj[key];
          const newKey = prefix ? `${prefix}.${key}` : key;
          if (value && typeof value === 'object' && !Array.isArray(value)) {
            Object.assign(res, this.flattenObject(value, newKey));
          } else {
            res[newKey] = value;
          }
        }
      }
      return res;
    },
    async fofaDelete(row) {
      console.log(row.id);

      try {
        await this.$confirm("此操作将永久删除该条记录, 是否继续?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        });
        const response = await downloaddeleteList(row.id);
        this.$message.success("用户删除成功");
        await this.fofaVpsListll();
        this.dialogVisibleZoomeyenName = false;
      } catch (error) {
        this.$message.error("用户取消删除，请稍后再试");
      }
    },
    submitFofa() {
      // 处理搜索逻辑
      // console.log("搜索条件：123123", this.user);
      console.log("搜索条件：123123", this.user);

      selseloadXlsVpsList(this.user).then((response) => {
        // 兼容 response 结构
        this.list = response.data ? response.data : response;
        console.log(this.list, 3333333333);
      }).catch((error) => {
        console.error("Error fetching data:", error);
      });
    },
    msgOne() {
      this.msg = 1;
      this.fofaVpsListll();
      this.dialogVisibleFofa = false;  // 关闭添加弹框
      this.editdialogVisibleFofa = false;  // 关闭编辑弹框
      this.dialogVisibleZoomeyenName = false;
    },
    msgTwo() {
      this.msg = 2;
      console.log(this.msg);
      this.dialogVisibleFofa = false;  // 关闭添加弹框
      this.editdialogVisibleFofa = false;  // 关闭编辑弹框
      this.dialogVisibleZoomeyenName = false;
    },
    handle(row) {
      this.detailData = row;
      this.dialogVisible = true;
      this.dialogVisibleFofa = false; // 确保关闭zoomeye添加弹框
    },
    fofaVpsListll() {
      fofaVpsList().then((response) => {
        // 兼容 response 结构
        this.list = response.data ? response.data : response;
        console.log(this.list);
      }).catch((error) => {
        console.error("Error fetching data:", error);
      });
    },
    handleSelectionChange(selection) {
      // 兼容后端返回的字段，优先取id，没有则取country_name
      this.ids = selection.map(item => item.id);
      console.log("选中的ID数组:", this.ids);
    },
    handleUpload() {
      console.log("下载按钮被点击，选中的ID数组:", this.ids);

      // 将选中的ids数组传递给downloadJsonVpsList接口
      downloadJsonVpsList(this.ids).then((response) => {
        const blob = new Blob([response.data], { type: 'application/octet-stream.json' }); // 或其他类型
        const url = window.URL.createObjectURL(blob);
        // 创建临时链接下载
        const link = document.createElement('a');
        link.href = url;
        link.download = 'file.json'; // 自定义文件名
        document.body.appendChild(link);
        link.click();

        // 清理
        window.URL.revokeObjectURL(url);
        document.body.removeChild(link);
      }).catch((error) => {
        console.error("下载 JSON 文件失败:", error);
      });
    },
    downloadXmlVpsList() {
      console.log("下载按钮被点击，选中的ID数组:", this.ids);

      // 将选中的ids数组传递给downloadJsonVpsList接口
      downloadXmlVpsList(this.ids).then((response) => {
        const blob = new Blob([response.data], { type: 'application/octet-stream.xml' }); // 或其他类型
        const url = window.URL.createObjectURL(blob);
        // 创建临时链接下载
        const link = document.createElement('a');
        link.href = url;
        link.download = 'file.xml'; // 自定义文件名
        document.body.appendChild(link);
        link.click();

        // 清理
        window.URL.revokeObjectURL(url);
        document.body.removeChild(link);
      }).catch((error) => {
        console.error("下载 XML 文件失败:", error);
      });
    },
    downloadXlsVpsList() {
      console.log("下载按钮被点击，选中的ID数组:", this.ids);

      // 将选中的ids数组传递给downloadJsonVpsList接口
      downloadXlsVpsList(this.ids).then((response) => {
        const blob = new Blob([response.data], { type: 'application/octet-stream.xls' }); // 或其他类型
        const url = window.URL.createObjectURL(blob);
        // 创建临时链接下载
        const link = document.createElement('a');
        link.href = url;
        link.download = 'file.xls'; // 自定义文件名
        document.body.appendChild(link);
        link.click();

        // 清理
        window.URL.revokeObjectURL(url);
        document.body.removeChild(link);
      }).catch((error) => {
        console.error("下载 XLS 文件失败:", error);
      });
    },
    // zoomeye接口
    handleZoomeye(row) {
      this.detailData = row;
      this.dialogVisibleZoomeye = true;
      this.dialogVisibleZoomeyenName = false; // 确保关闭zoomeye添加弹框
      this.dialogVisibleZoomeyenEdit = false; // 确保关闭zoomeye
    },
    zoomeyeVpsList() {
      zoomeyeVpsList().then((response) => {

        // 兼容 response 结构
        this.listzoomeye = response.data ? response.data : response;
        console.log(this.listzoomeye, "zoomeye数据");
        console.log(this.listzoomeye.length, "zoomeye数据");
      }).catch((error) => {
        console.error("Error fetching data:", error);
      });
    },
    handleSelectionChangeZoomeye(selection) {
      // 兼容后端返回的字段，优先取id，没有则取country_name
      this.idszoomeye = selection.map(item => item.id);
      console.log("选中的ID数组:", this.idszoomeye);
    },
    handleUploadZoomeye() {
      console.log("下载按钮被点击，选中的ID数组:", this.idszoomeye);
      let ids = this.idszoomeye;

      // 将选中的ids数组传递给downloadJsonVpsList接口
      zoomeyeJsonsList(ids).then((response) => {
        const blob = new Blob([response.data], { type: 'application/octet-stream.json' }); // 或其他类型
        const url = window.URL.createObjectURL(blob);
        // 创建临时链接下载
        const link = document.createElement('a');
        link.href = url;
        link.download = 'file.json'; // 自定义文件名
        document.body.appendChild(link);
        link.click();

        // 清理
        window.URL.revokeObjectURL(url);
        document.body.removeChild(link);
      }).catch((error) => {
        console.error("下载 JSON 文件失败:", error);
      });
    },
    downloadXmlVpsListZoomeye() {
      console.log("下载按钮被点击，选中的ID数组:", this.idszoomeye);
      let ids = this.idszoomeye;
      // 将选中的ids数组传递给downloadJsonVpsList接口
      zoomeyeXmlList(ids).then((response) => {
        const blob = new Blob([response.data], { type: 'application/octet-stream.xml' }); // 或其他类型
        const url = window.URL.createObjectURL(blob);
        // 创建临时链接下载
        const link = document.createElement('a');
        link.href = url;
        link.download = 'file.xml'; // 自定义文件名
        document.body.appendChild(link);
        link.click();

        // 清理
        window.URL.revokeObjectURL(url);
        document.body.removeChild(link);
      }).catch((error) => {
        console.error("下载 XML 文件失败:", error);
      });
    },
    downloadXlsVpsListZoomeye() {
      console.log("下载按钮被点击，选中的ID数组:", this.idszoomeye);
      let ids = this.idszoomeye;
      // 将选中的ids数组传递给downloadJsonVpsList接口
      zoomeyeXlsList(ids).then((response) => {
        const blob = new Blob([response.data], { type: 'application/octet-stream.xls' }); // 或其他类型
        const url = window.URL.createObjectURL(blob);
        // 创建临时链接下载
        const link = document.createElement('a');
        link.href = url;
        link.download = 'file.xls'; // 自定义文件名
        document.body.appendChild(link);
        link.click();

        // 清理
        window.URL.revokeObjectURL(url);
        document.body.removeChild(link);
      }).catch((error) => {
        console.error("下载 XLS 文件失败:", error);
      });
    },
    formatTime(val) {
      // 支持时间戳和ISO字符串
      if (!val) return '';
      let date;
      if (/^\d+$/.test(val)) {
        // 纯数字，可能是时间戳
        date = new Date(Number(val));
      } else {
        date = new Date(val);
      }
      if (isNaN(date.getTime())) return val;
      const y = date.getFullYear();
      const m = (date.getMonth() + 1).toString().padStart(2, '0');
      const d = date.getDate().toString().padStart(2, '0');
      const h = date.getHours().toString().padStart(2, '0');
      const min = date.getMinutes().toString().padStart(2, '0');
      const s = date.getSeconds().toString().padStart(2, '0');
      return `${y}-${m}-${d} ${h}:${min}:${s}`;
    },
  }
};
</script>

<style scoped>
.upload-demo.light-upload {
  background: linear-gradient(135deg, #f8fafc 60%, #e9f0fb 100%);
  border-radius: 14px;
  box-shadow: 0 4px 24px #b3c6e822, 0 2px 12px #e9f0fb;
  padding: 36px 32px 28px 32px;
  margin: 32px auto 0 auto;
  max-width: 900px;
  min-width: 320px;
  color: #232526;
}

.btn-bar {
  margin-bottom: 18px;
  display: flex;
  gap: 16px;
}

.dark-btn {
  background: linear-gradient(90deg, #409eff 60%, #53caff 100%) !important;
  color: #fff !important;
  border: none !important;
  border-radius: 8px !important;
  font-weight: 600;
  font-size: 15px;
  box-shadow: 0 2px 8px #b3c6e822;
  transition: background 0.18s, box-shadow 0.18s;
  padding: 8px 22px;
}

.dark-btn:hover {
  background: linear-gradient(90deg, #53caff 60%, #409eff 100%) !important;
  color: #fff !important;
  box-shadow: 0 4px 18px #b3c6e822;
}

.dark-table {
  background: #f8fafc !important;
  border-radius: 10px !important;
  color: #232526 !important;
  box-shadow: 0 2px 12px #b3c6e822;
}

.dark-table ::v-deep .el-table__header,
.dark-table ::v-deep .el-table__body {
  background: #f8fafc !important;
  color: #409eff !important;
}

.dark-table ::v-deep th,
.dark-table ::v-deep td {
  background: #f8fafc !important;
  color: #232526 !important;
  border-bottom: 1px solid #b3c6e8 !important;
}

.dark-table ::v-deep .el-table__row:hover>td {
  background: #e9f0fb !important;
  color: #409eff !important;
}

.dark-table ::v-deep .el-table__body tr.current-row>td {
  background: #e9f0fb !important;
  color: #409eff !important;
}

.dark-table ::v-deep .el-table__body-wrapper {
  border-radius: 10px !important;
}

.dark-table ::v-deep .el-table__column-resize {
  background: #409eff !important;
}

.dark-table ::v-deep .el-table__row .el-checkbox__input.is-checked .el-checkbox__inner {
  background: #409eff !important;
  border-color: #53caff !important;
}

.dark-table ::v-deep .el-checkbox__inner {
  background: #f8fafc !important;
  border: 1.5px solid #409eff !important;
}

.dark-table ::v-deep .el-checkbox__input.is-checked .el-checkbox__inner::after {
  border-color: #fff !important;
}

.switch-btn-bar {
  display: flex;
  gap: 18px;
  justify-content: flex-start;
  margin-bottom: 22px;
}

.switch-btn {
  background: linear-gradient(90deg, #f8fafc 60%, #e9f0fb 100%) !important;
  color: #409eff !important;
  border: 2px solid #409eff !important;
  font-weight: 600;
  font-size: 16px;
  border-radius: 22px !important;
  padding: 8px 32px !important;
  box-shadow: 0 2px 8px #b3c6e822;
  transition: background 0.18s, color 0.18s, border 0.18s;
}

.switch-btn.active,
.switch-btn:hover {
  background: linear-gradient(90deg, #409eff 60%, #53caff 100%) !important;
  color: #fff !important;
  border-color: #53caff !important;
  box-shadow: 0 4px 18px #b3c6e822;
}

.detail-card {
  background: #fff;
  border-radius: 16px;
  box-shadow: 0 2px 12px #b3c6e822;
  padding: 28px 24px 18px 24px;
  margin: 0 auto;
  min-width: 320px;
  max-width: 700px;
}

.wide-detail-card {
  max-width: 1000px;
  min-width: 600px;
}

.detail-title {
  font-size: 22px;
  color: #409eff;
  font-weight: 700;
  margin-bottom: 18px;
  letter-spacing: 1px;
  text-align: left;
}

.detail-grid-row3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px 24px;
}

.detail-row {
  display: flex;
  align-items: flex-start;
  font-size: 15px;
  color: #232526;
  font-weight: 500;
  padding: 2px 0;
  word-break: break-all;
}

.detail-label {
  color: #409eff;
  font-weight: 600;
  min-width: 60px;
  margin-right: 6px;
  font-size: 15px;
  flex-shrink: 0;
}

.detail-value {
  color: #232526;
  word-break: break-all;
  font-size: 15px;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}

.input-id {
  width: 200px;
  margin-bottom: 10px;
  border-radius: 8px;
  background: #f8fafc !important;
  border: 1.5px solid #b3c6e8 !important;
  color: #409eff !important;
  font-size: 15px;
  transition: border 0.18s, box-shadow 0.18s;
}

.input-id:focus,
.input-id .el-input__inner:focus {
  border-color: #409eff !important;
  box-shadow: 0 0 4px #53caff33;
  background: #fff !important;
}

.search-input ::v-deep .el-input__inner {
  background: #f8fafc !important;
  color: #409eff !important;
  border: none !important;
  height: 36px !important;
  line-height: 36px !important;
  font-size: 15px;
  border-radius: 8px !important;
}

.search-btn {
  min-width: 80px;
  font-weight: 600;
  border-radius: 8px;
  margin-bottom: 10px;
  background: linear-gradient(90deg, #409eff 60%, #53caff 100%) !important;
  color: #fff !important;
  border: none !important;
  box-shadow: 0 2px 8px #b3c6e822;
  transition: background 0.18s, box-shadow 0.18s;
}

.search-btn:hover {
  background: linear-gradient(90deg, #53caff 60%, #409eff 100%) !important;
  color: #fff !important;
  box-shadow: 0 4px 18px #b3c6e822;
}

.search-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 18px;
  justify-content: flex-start;
  /* 左对齐 */
}
</style>
